package com.kanesoft.android.gdx.actors;

import java.util.Iterator;
import java.util.Vector;

import com.badlogic.gdx.Gdx;

public class ActorEventsBroadcast {

    private Vector<ActorObject> listeners;

    private boolean screenWasTouched;

    /**
     * One Constructor for SCREEN.
     */
    public ActorEventsBroadcast() {
        listeners = new Vector<ActorObject>();
    }

    
    public void updateActorsPositions() {
        notifyActorsToUpdatePosition();
    }
    
    
    /**
     * Call this method in Game.render() to publish touch events all over the
     * framework
     */
    public void updateEvents(float deltaTime, float camOffsX, float camOffsY) {
        
        if (Gdx.input.justTouched()) {
            screenWasTouched = true;
            broadcastOnPressDown(Gdx.input.getX(), Gdx.graphics.getHeight()
                    - Gdx.input.getY());
        }

        if ((screenWasTouched) && (Gdx.input.isTouched() == false)) {
            screenWasTouched = false;
            broadcastOnPressUp(Gdx.input.getX(), Gdx.graphics.getHeight()
                    - Gdx.input.getY());
        }
        
        
        checkSpriteCollision();
        
        notifyActorsToDraw(deltaTime, camOffsX, camOffsY);

    }

    /**
     * Used this method to register the widget to receive events
     * 
     * @param objectListening
     */
    public void addActorObject(ActorObject objectListening) {
        if (objectListening == null)
            return;

        listeners.add(objectListening);
    }
    
    /**
     * Use this method to de-register a widget
     * @param objectListening
     */
    public void removeActorObject(ActorObject objectListening) {
        if (objectListening == null)
            return;

        listeners.remove(objectListening);
    }

    private void notifyActorsToUpdatePosition() {
        Vector<ActorObject> listCopy = new Vector<ActorObject>(listeners);
        
        for (Iterator<ActorObject> i = listCopy.iterator(); i.hasNext();) {
            ActorObject objectListening = i.next();
            objectListening.updateActorPositions();
        }
    }
    
    private void checkSpriteCollision() {
        Vector<ActorObject> listCopy = new Vector<ActorObject>(listeners);
        
        for (Iterator<ActorObject> i = listCopy.iterator(); i.hasNext();) {
            ActorObject objectCollidingA = i.next();
            
            for (Iterator<ActorObject> j = listCopy.iterator(); j.hasNext();) {
                ActorObject objectCollidingB = j.next();
                
                if (objectCollidingA.equals(objectCollidingB)) continue;
                
                if (objectCollidingA.getActorWidget().isWidgetOverlapping(objectCollidingB.getActorWidget())) {
                    if ((objectCollidingA.getActorWidget().enabled) && (objectCollidingB.getActorWidget().enabled)) {
                        objectCollidingA.handleActorsCollision(objectCollidingB);
                    }
                }
            }            
        }
    }
    
    
    private void notifyActorsToDraw(float deltaTime, float camOffsX, float camOffsY) {
        Vector<ActorObject> listCopy = new Vector<ActorObject>(listeners);
        
        for (Iterator<ActorObject> i = listCopy.iterator(); i.hasNext();) {
            ActorObject objectListening = i.next();
            objectListening.getActorWidget().draw(deltaTime, camOffsX, camOffsY);
        }
    }
    
    private void broadcastOnPressDown(int x, int y) {
        Vector<ActorObject> listCopy = new Vector<ActorObject>(listeners);
        
        for (Iterator<ActorObject> i = listCopy.iterator(); i.hasNext();) {
            ActorObject objectListening = i.next();
            objectListening.getActorWidget().onPressDown(x, y);
        }
    }

    private void broadcastOnPressUp(int x, int y) {
        Vector<ActorObject> listCopy = new Vector<ActorObject>(listeners);
        
        for (Iterator<ActorObject> i = listCopy.iterator(); i.hasNext();) {
            ActorObject objectListening = i.next();
            objectListening.getActorWidget().onPressUp(x, y);
        }
    }

}
